package com.xxx.mch.aspject;

import javax.servlet.http.HttpServletRequest;

import com.alibaba.fastjson.JSON;
import com.xxx.mch.config.MchInterepter;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @author FengHaixin
 * @description 一句话描述该文件的用途
 * @date 2020/2/26
 */
@Slf4j
@Aspect
@Component
@Order (Integer.MIN_VALUE)
public class RequestLogAspectj
{
    @Pointcut ("execution(public * com.xxx.mch.controller.*Controller.*(..))")
    public void pointCut()
    {
    }


    @Around (value = "pointCut()")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable
    {
        long start = System.currentTimeMillis();

        Signature sig = joinPoint.getSignature();
        if (!(sig instanceof MethodSignature)) {
            throw new IllegalArgumentException(sig + "该注解只能用于方法");
        }
        MethodSignature msig = (MethodSignature) sig;
        Object target = joinPoint.getTarget();
        Method currentMethod = target.getClass().getMethod(msig.getName(), msig.getParameterTypes());
        RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = ((ServletRequestAttributes)requestAttributes).getRequest();
        String str = Arrays.asList(joinPoint.getArgs()).stream().map(value ->
            value == null ? " " : value.toString()
        ).collect(Collectors.joining(","));
        log.info("uid:{}, controller-method: {}, method: {}, uri: {}, param: {}", MchInterepter.UID.get().getUid(), target.getClass().getSimpleName() + "_" + currentMethod.getName(), request.getMethod(), request.getRequestURI(), str);
        Object proceed = joinPoint.proceed();
        long cost = System.currentTimeMillis() - start;
        log.info("method: {}, uri: {}, cost: {}, response: {}", request.getMethod(), request.getRequestURI(), cost, proceed);
        return proceed;
    }
}
